package edu.ntu.im.p2ptrade.action;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONObject;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import edu.ntu.im.p2ptrade.action.AjaxResponse.ErrorCode;



public abstract class AjaxAction extends Action {

	private final Log log = LogFactory.getLog(AjaxAction.class);

	public abstract AjaxResponse execute(HttpServletRequest request);

	public static AjaxResponse success() {
		return success(null);
	}

	public static AjaxResponse success(Object result) {
		AjaxResponse ajaxResponse = new AjaxResponse();
		ajaxResponse.setSuccess(true);
		ajaxResponse.setErrorCode(AjaxResponse.ErrorCode.OK);
		ajaxResponse.setResult(result);
		return ajaxResponse;
	}
	
	

	public AjaxResponse fail(String message) {
		return fail(message, null, AjaxResponse.ErrorCode.UncategorizedError);
	}

	public AjaxResponse fail(Throwable e) {
		return fail(null, e, AjaxResponse.ErrorCode.UncategorizedError);
	}

	public AjaxResponse fail(String message, ErrorCode errorCode) {
		return fail(message, null, errorCode);
	}

	public AjaxResponse fail(Throwable e, ErrorCode errorCode) {
		return fail(null, e, errorCode);
	}

	private AjaxResponse fail(String message, Throwable e, ErrorCode errorCode) {
		AjaxResponse ajaxResponse = new AjaxResponse();
		ajaxResponse.setSuccess(false);
		ajaxResponse.setErrorCode(errorCode);
		if (message != null && message.length() > 0) {
			ajaxResponse.setErrorMessage(message);
		} else if (e != null) {
			StringBuffer sb = new StringBuffer(60);
			appendError(sb, e);
			ajaxResponse.setErrorMessage(sb.toString());
		}
		if (errorCode.getCode() > ErrorCode.UncategorizedError.getCode()) {
			ajaxResponse.setErrorCode(errorCode);
		} else {
			ajaxResponse.setErrorCode(ErrorCode.UncategorizedError);
		}

		return ajaxResponse;
	}

	private static void appendError(StringBuffer sb, Throwable t) {
		if (t == null) {
			return;
		}
		sb.append(t.getClass().getName());
		String m = t.getMessage();
		if (m != null && m.length() > 0 && (m.indexOf("Exception:") < 0)) {
			sb.append(": ");
			sb.append(m);
		}
		sb.append('\n');
		appendError(sb, t.getCause());
	}

	public ActionForward execute(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response) {
		response.setContentType("text/plain");
		response.setHeader("Cache-Control", "no-cache");
		response.setHeader("Pragma", "no-cache");
		AjaxResponse ajaxResponse = execute(request);
		// Object result = new JsonSerializer().serialize(ajaxResponse);
		JSONObject result = JSONObject.fromObject(ajaxResponse);
		try {
			result.write(response.getWriter());
		} catch (Exception e) {
			if (log.isErrorEnabled()) {
				log.error("Exception in execute()", e);
			}
		}
		return null;
	}
}